Search APIs
Search capability is an important component of many REST APIs. Search is usually used to find resources within a collection that meet the API Consumers requirements.
There are two common ways to search collections via API:
- GET with query parameters
- POST with query parameters in a request body
Both of the above mechanisms are supported by this standard however there are some considerations when choosing the approach.
GET | POST | |
---|---|---|
Description | Retrieve n resources from a collection using the GET HTTP method that match parameters provided on in a query string - GET /groups?status=active | Retrieve n resources from a collection using the POST HTTP method that match parameters provided on in a query string - POST /groups {"status":"active"} |
Considerations |
|
|
Example
# Get a list of groups that are either active or inactive, sorted by name and status
GET https://api.example.govt.nz/groups?status=active,inactive&sort=name,status
{
"groups": [
{
"id": "0219c539-5885-4ab6-a55b-b0de7537c426",
"name": "API lovers",
"status": "active"
},
{
"id": "1219c539-5885-4ab6-a55b-b0de7537c427",
"name": "Developers",
"status": "active"
},
{
"id": "7219c539-5885-4ab6-a55b-b0de7537c42c",
"name": "Risk analysts",
"status": "active"
},
{
"id": "3219c539-5885-4ab6-a55b-b0de7537c42h",
"name": "Writers",
"status": "active"
},
{
"id": "g219c539-5885-4ab6-a55b-b0de7537c425",
"name": "Authors",
"status": "inactive"
}
],
"_links": [
{
"rel": "self",
"href": "https://api.example.govt.nz/groups?sort=status,name"
},
{
"rel": "API Lovers",
"href": "https://api.example.govt.nz/groups/0219c539-5885-4ab6-a55b-b0de7537c426"
},
{
"rel": "Developers",
"href": "https://api.example.govt.nz/groups/1219c539-5885-4ab6-a55b-b0de7537c427"
},
{
"rel": "Risk analysts",
"href": "https://api.example.govt.nz/groups/7219c539-5885-4ab6-a55b-b0de7537c42c"
},
{
"rel": "Writers",
"href": "https://api.example.govt.nz/groups/3219c539-5885-4ab6-a55b-b0de7537c42h"
},
{
"rel": "Authors",
"href": "https://api.example.govt.nz/groups/g219c539-5885-4ab6-a55b-b0de7537c425"
}
]
}
Template
POST /{version}/{namespace}/{search-resource}
Example Request
POST /v1/people/person-search?page=5 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"startDateBefore": "2010-01-01",
"position": "Manager",
"businessUnit": "Operations",
"many other search parameters": ""
}
Example Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"pageSize": 10,
"page": 5,
"totalItems": 77,
"totalPages": 8,
"items": [
"lots of people objects here"
],
"_links": [
{
"rel": "first",
"href": "https://www.example.com/v1/people/person-search?page=1"
},
{
"rel": "prev",
"href": " https://www.example.com/v1/people/person-search?page=4"
},
{
"rel": "next",
"href": " https://www.example.com/v1/people/person-search?page=6"
},
{
"rel": "last",
"href": " https://www.example.com/v1/people/person-search?page=8"
}
]
}
Other considerations include special characters or filters that add additional complexity due to URL encoding requirements. For example, the search function might need to support "<” or ">” operators, or special characters for non-English language support. Additionally, structured query language (SQL) words should be avoided as common threat detection filters may block requests containing words such as ‘DROP’, ‘ALTER’ or ‘DELETE’ in case they are SQL injection attacks. See OWASP XSS Cheat Sheet and OWASP SQL Injection Cheat Sheet for details.
Paging behaviour for search results should be consistent with the interaction as described in Query Arguments. Pagination can be implemented as a page number and page size, offset and limit, or continuation token, depending on the scale and changeability of the search results.
Note: It is worth pointing out that since the HTTP protocol treats POST operations as unsafe, the result is not cacheable. This applies even if the response has a Cache-Control header included, so consider the performance impacts on the API if this is a high-volume operation.